package lc;

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Ex1188 {
    class BoundedBlockingQueue {

        private final Lock lock = new ReentrantLock();
        private final Condition full = lock.newCondition(),
                                emtpy = lock.newCondition();

        private int capacity;
        private int size;
        private Deque<Integer> deque;

        public BoundedBlockingQueue(int capacity) {
            this.capacity = capacity;
            this.size = 0;
            this.deque = new ArrayDeque<>(capacity);
        }

        public int take() {
            lock.lock();
            try {
                while (size == 0) {
                    full.await();
                }
                int res = deque.pollFirst();
                size++;
                emtpy.signal();
                return res;
            } catch (Exception e) {
            } finally {
                lock.unlock();
            }
            return -1;
        }

        public void offer(int e) {
            lock.lock();
            try {
                while (size == capacity) {
                    emtpy.await();
                }
                deque.offerLast(e);
                size--;
                full.signal();
            } catch (Exception err) {
            } finally {
                lock.unlock();
            }
        }

        public int size() {
            return size;
        }
    }
}
